<script setup>
import { ref } from "vue";
import "@material/web/icon/icon.js";
import "@material/web/iconbutton/icon-button.js";
import "@material/web/button/text-button.js";
import { listDevice, updateDevice } from "@/api/device";
import MaterialTable from "@/components/MaterialTable.vue";
import DeviceItem from "./DeviceItem.vue";
import AddDeviceDialog from "./AddDeviceDialog.vue";
import AddDeviceSucceedDialog from "./AddDeviceSucceedDialog.vue";
import DeviceCertificateDialog from "./DeviceCertificateDialog.vue";
import DeleteDeviceDialog from "./DeleteDeviceDialog.vue";
import MaterialDialog from "@/components/MaterialDialog.vue";
import SnackBar from "@/components/SnackBar.vue";
import ErrorSnackBar from "@/components/ErrorSnackBar.vue";
import LoadingLayer from "@/components/LoadingLayer.vue";

const devices = ref([]);
const snackBarMessage = ref(null);
const failed = ref(false);
const dialogMessage = ref(null);
const loading = ref(false);
const deviceError = ref(undefined);
const addDeviceOpened = ref(false);
const addedDevice = ref(null);
const deviceCertificate = ref(null);
const deleteDeviceOpened = ref(false);
const deletingDevice = ref(null);

async function requireDevices(refresh = true) {
  try {
    if (refresh) {
      loading.value = true;
    }
    devices.value = await listDevice();
  } catch (ex) {
    deviceError.value = ex;
  } finally {
    loading.value = false;
  }
}

requireDevices();

function addDeviceDone(device) {
  addedDevice.value = device;
  requireDevices(false);
}

async function toggleDevice(id, enabled) {
  try {
    await updateDevice(id, {
      enabled
    });
    snackBarMessage.value = { message: "操作成功" };
    requireDevices(false);
  } catch (message) {
    failed.value = true;
    dialogMessage.value = { title: "操作失败", message };
  }
}

function deleteDevice(device) {
  deleteDeviceOpened.value = true;
  deletingDevice.value = device;
}

</script>

<template>
  <div class="device-manage-table">
    <MaterialTable>
      <thead>
        <tr>
          <th>ID</th>
          <th>设备名</th>
          <th>状态</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody id="devices-body">
        <LoadingLayer fill :loading="loading"></LoadingLayer>
        <DeviceItem v-for="device in devices" :key="device.id" :device="device"
          @disable="toggleDevice(device.id, false)" @enable="toggleDevice(device.id, true)"
          @cert="deviceCertificate = device.certificate" @delete="deleteDevice(device)">
        </DeviceItem>
        <tr>
          <td colspan="4">
            <md-text-button @click="addDeviceOpened = true">
              新建设备
            </md-text-button>
          </td>
        </tr>
      </tbody>
    </MaterialTable>

    <AddDeviceDialog :open="addDeviceOpened" @close="addDeviceOpened = false"
      @error="message => { failed = true; dialogMessage = { title: '设备添加失败', message } }" @done="addDeviceDone">
    </AddDeviceDialog>
    <AddDeviceSucceedDialog :device="addedDevice" @close="addedDevice = null">
    </AddDeviceSucceedDialog>
    <DeleteDeviceDialog :device="deletingDevice" :open="deleteDeviceOpened" @close="deleteDeviceOpened = false"
      @error="message => { failed = true; dialogMessage = { title: '设备删除失败', message } }" @done="requireDevices(false)">
    </DeleteDeviceDialog>
    <DeviceCertificateDialog :certificate="deviceCertificate" @close="deviceCertificate = null">
    </DeviceCertificateDialog>

    <MaterialDialog :open="failed" @close="failed = false">
      <template #headline>
        {{ dialogMessage?.title }}
      </template>

      <template #content>
        <form id="failed-dialog" method="dialog">
          {{ dialogMessage?.message }}
        </form>
      </template>

      <template #actions>
        <md-text-button autofocus type="submit" form="failed-dialog">确定</md-text-button>
      </template>
    </MaterialDialog>

    <SnackBar :show="snackBarMessage != null" @close="snackBarMessage = null">
      {{ snackBarMessage?.message }}
    </SnackBar>

    <ErrorSnackBar :error="deviceError"></ErrorSnackBar>
  </div>
</template>

<style scoped>
#loading-layer {
  width: 100%;
  height: 100%;
}

.device-manage-table tr,
.device-manage-table tr {
  white-space: nowrap;
}

.device-manage-table tbody {
  position: relative;
}
</style>

<style>
.device-manage-table td:nth-child(2),
.device-manage-table th:nth-child(2) {
  width: 100%;
  text-align: left;
}
</style>